home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Calc ControlRgn.c
-
- Contains: This sample shows how to call a CDEF to get the control's Region.
-
- Written by: Matthew Xavier Mora
-
- Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/19/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
- 02-28-96 mxm added more comments and error checking
- 05-07-96 mxm got it ready for the cd
-
-
- */
-
- #include <Resources.h>
- #include <Errors.h>
- #include <Windows.h>
-
- #include "SAL_Public.h"
-
- #define kPaintRegionOffset ( 200 )
- #define kNoOffset ( 0 )
- #define kNextButtonOffset ( 50 )
- #define kScrollBarFudge ( 15 )
- #define kMemorySystemErrMsg "\pMemory Manager error"
- #define kOurWindowTitle "\pCalculate a Control's Region Sample"
- #define kBadThingsMsg "\pBad things happened"
-
- pascal SInt16 DoButtonHit(ButtonItemRef me, SInt32 modifiers);
-
-
- //-------------------------------------------------------------------------
- // This function checks MemError and reports any errors returned
- //-------------------------------------------------------------------------
- static OSErr CheckMemoryError(void)
- //-------------------------------------------------------------------------
- {
- OSErr err;
-
- err = MemError();
- if (err) {
- SAL_ErrorMessage(kMemorySystemErrMsg,err,kSAL_NonFatalError);
- }
- return err;
- }
-
- //-------------------------------------------------------------------------
- // A utility routine to lock a Handle and report any errors. It returns the
- // the state of the handle before it was locked so you can reset the handle
- // to its original state.
- //-------------------------------------------------------------------------
- static OSErr MyLockHandle(Handle theHandle,SInt8 * state)
- //-------------------------------------------------------------------------
- {
- OSErr err = noErr;
- SInt8 tempState;
-
- tempState = HGetState(theHandle); // remember the state
- err = CheckMemoryError(); // alert the user if error
- if (err == noErr) {
- HLock(theHandle);
- err = CheckMemoryError();
- }
- if (state) {
- *state = tempState;
- }
- return err;
- }
-
- //-------------------------------------------------------------------------
- // A utility routine to Set a Handle state and report any errors.
- //-------------------------------------------------------------------------
- static OSErr MySetHandleState(Handle theHandle,SInt8 state)
- //-------------------------------------------------------------------------
- {
- OSErr err = noErr;
-
- HSetState(theHandle,state); // remember the state
- err = CheckMemoryError(); // report any errors
- return err; // return error
- }
-
- //-------------------------------------------------------------------------
- // GetControlRgn takes a control handle and an existing Rgn
- // as parameters and will return in the control's rgn
- //-------------------------------------------------------------------------
- pascal OSStatus GetControlRegion(ControlHandle ch,ControlPartCode inPart,RgnHandle theRgn)
- //-------------------------------------------------------------------------
- {
- #pragma unused(inPart)
- Handle cdefHandle; // Handle to the control Proc
- SInt16 errorState = noErr ; // preset error state
-
- if ( (ch != nil) && (theRgn != nil) ) { // make sure we have a control and Rgn
- cdefHandle = (**ch).contrlDefProc; // Get the control's Handle
- if (!*cdefHandle) { // lets load it in if its not
- LoadResource(cdefHandle);
- errorState = ResError(); // check for error
- }
- if ((*cdefHandle) != nil && errorState == noErr ) { // all is well
- SInt8 state ; // holding place for handle state
- errorState = MyLockHandle(cdefHandle,&state);
- if (errorState == noErr) {
- UInt32 result; // the result we don't care about
- ControlDefUPP myControlUPP; // Holding place for the CDEF ProcPtr or UPP
- //
- myControlUPP = (ControlDefUPP)(*cdefHandle);
- // What? Casting to a UPP? Are you crazy?
- // The reason you cast in instead of creating a UPP
- // is that it may already be a UPP (ie native CDEF)
- // and dual UPP's would really confuse Mixed Mode. If its not
- // a upp, CallControlDefProc does the right thing by passing a
- // a valid ProcInfo to CallUniversalProc which makes
- // mixed mode a happy camper in any case.
- result = CallControlDefProc(myControlUPP,
- GetControlVariant(ch),
- ch,
- calcCntlRgn,
- (SInt32)theRgn);
- errorState = MySetHandleState(cdefHandle,state); // reset the handle state
- }
- }
- } else { // ControlHandle or theRgn is nil
- errorState = nilHandleErr; // set the error
- }
- return (errorState); // be sure and return any errors
- }
-
- //-------------------------------------------------------------------------
- // Simple routine to paint the region we get from the Control
- //-------------------------------------------------------------------------
- static OSErr DisplayControlRgn(ControlHandle ch)
- //-------------------------------------------------------------------------
- {
- RgnHandle theRgn;
- SInt16 err = noErr;
-
- theRgn = NewRgn(); // Get a region to work with
- if (theRgn) {
- err = GetControlRegion(ch,0,theRgn); // Get the Button's Region
- if (err == noErr){
- OffsetRgn(theRgn,kPaintRegionOffset,kNoOffset);
- PaintRgn(theRgn);
- DisposeRgn(theRgn);
- } else {
- err = CheckMemoryError();
- }
- }
- return (err);
- }
-
-
- //-------------------------------------------------------------------------
- // This gets called when the Click Me button is clicked.
- // ------------------------------------------------------------------------
- // Note!
- // There is a problem with global optimization and call back functions.
- // If you want global optimization on for the rest of your code you
- // should turn it off for any call back functions unless MW has released
- // a fix. i.e #pragma optimization_level 1
- //-------------------------------------------------------------------------
- static pascal short DoButtonHit(const ButtonItemRef me,const long modifiers)
- //-------------------------------------------------------------------------
- {
- #pragma unused (modifiers)
-
- ControlHandle cr = nil;
- OSErr err = noErr;
-
- cr = (ControlHandle) SAL_GetObjectHandle((SInt32) me);
- if (cr) {
- err = DisplayControlRgn(cr);
- if (err != noErr) {
- SAL_ErrorMessage(kBadThingsMsg,err,kSAL_NonFatalError);
- }
- }
- return err;
- }
-
- //-------------------------------------------------------------------------
- // This gets called when the Clear button is clicked.
- //-------------------------------------------------------------------------
- static pascal SInt16 DoClear(const ButtonItemRef me,const SInt32 modifiers)
- //-------------------------------------------------------------------------
- {
- #pragma unused (modifiers)
- #pragma unused (me)
- Rect r;
-
- r = gSAL_CurrentWindow->portRect; // Get the window's portRect
- r.left += kPaintRegionOffset; // offset so it doesn't erase
- r.right -= kScrollBarFudge; // our buttons and scroll bar
- r.bottom -= kScrollBarFudge; // areas
- InvalRect(&r);
- return noErr;
- }
-
- //-------------------------------------------------------------------------
- // This is the main function. Note how simple it is. It installs
- // two Buttons and then lets SimpleApp handle the rest.
- //
- //-------------------------------------------------------------------------
- void main(void)
- //-------------------------------------------------------------------------
- {
- Rect r;
- SInt16 gMyWindowID;
- SInt16 err;
-
- SAL_InitSimpleApp(1,kSAL_UseStandardMenu); // Simple App Sets up the Tool Box For us
- gMyWindowID = SAL_GetDocumentWindow(128,nil); // Get our stored window
- // the global gSAL_CurrentWindow is maintained
- // by SimpleApp and it contains the active
- // document window reference
- SetWTitle(gSAL_CurrentWindow,kOurWindowTitle);// set the window title so we know what we are running
- SetRect(&r,10,30,100,50); // set the control bounds
- err = SAL_InstallPushButton (0, // Reference ID (we don't care)
- gSAL_CurrentWindow, // Owner Window
- "\pClick Me", // Name
- &r, // Bounds
- kSAL_NoCommandKey, // Command Key
- DoButtonHit , // Button Hit
- nil // Button Update Proc
- );
- OffsetRect(&r,kNoOffset,kNextButtonOffset);
- err = SAL_InstallPushButton (0, // Reference ID (we don't care)
- gSAL_CurrentWindow, // Owner Window
- "\pClear", // Name
- &r, // Bounds
- kSAL_NoCommandKey, // Command Key
- DoClear , // Button Hit Proc
- nil // Button Update Proc
- );
- SAL_Run(); // Let SimpleApp handle the rest
- }
-
-